﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Polly;
using SqlSugar;
using System.Net.Sockets;
using System.Security.Claims;
using System.Text.Encodings.Web;
using XinLife.Application.Interface;
using XinLife.Common.Filters;
using XinLife.Model;

namespace XinLife.Common
{
    /// <summary>
    /// 身份认证
    /// </summary>
    public class AuthentHandler : AuthenticationHandler<AuthenticationSchemeOptions>
    {
        private readonly IAuthorizeService _authorizeService;

        public AuthentHandler(IAuthorizeService authorizeService, IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
        {
            _authorizeService = authorizeService;
        }
        /// <summary>
        /// 设置当前请求的用户和角色
        /// </summary>
        /// <returns></returns>
        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            var context = Request.HttpContext;
            var endpoint = context.GetEndpoint();
            if (endpoint != null)
            {
                var hasToken = context.Request.Headers.TryGetValue("Authorization", out var authHeader);
                var allowAnonymous = endpoint.Metadata.GetMetadata<AllowAnonymousAttribute>();
                if (allowAnonymous != null && !hasToken)
                {
                    // 当前请求允许匿名访问
                    context.Items["user"] = new User() { cName = "anonymous", Roles = new List<Role>() };
                }
                else
                {
                    if (allowAnonymous != null && hasToken)
                    {
                        // 当前请求允许匿名访问
                        context.Items["user"] = new User() { cName = "anonymous", Roles = new List<Role>() };
                    }
                    if (context.User.Identity.IsAuthenticated)
                    {
                        string userId = context.User.Claims.First(t => t.Type == ClaimTypes.NameIdentifier).Value;

                        var user = await _authorizeService.GetUser(userId);
                        context.Items["user"] = user;
                        TimeoutExitService.ConnectionUsers.AddOrUpdate(userId, DateTime.Now, (key, oldValue) => DateTime.Now);
                    }
                }
            }
            return await context.AuthenticateAsync();

            //  // 获取请求中的身份验证信息
            //if (!Request.Headers.ContainsKey("Authorization"))
            //{
            //    // 如果请求头中没有包含Authorization，则返回未授权的结果
            //    return Task.FromResult(AuthenticateResult.Fail("Missing Authorization header"));
            //}

            //string authHeader = Request.Headers["Authorization"];
            //// 进行身份验证逻辑，例如检查身份验证令牌的有效性
            //if (authHeader=="11")
            //{
            //    return Task.FromResult(AuthenticateResult.Fail(new Exception()));
            //}
            //var claims = new[]
            //   {
            //        new Claim(ClaimTypes.NameIdentifier, "1"),
            //        new Claim(ClaimTypes.Name, "Fengfeng")
            //        // 可以根据需要添加其他声明
            //    };
            //var identity = new ClaimsIdentity(claims, Scheme.Name);
            //var principal = new ClaimsPrincipal(identity);
            //var ticket = new AuthenticationTicket(principal, Scheme.Name);
            //return  Task.FromResult(AuthenticateResult.Success(ticket));

        }
        protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
        {
            Response.ContentType = "application/json";
            Response.StatusCode = StatusCodes.Status401Unauthorized;
            await Response.WriteAsync(JsonConvert.SerializeObject(new { code = 401 }));
        }

        protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
        {
            Response.ContentType = "application/json";
            Response.StatusCode = StatusCodes.Status403Forbidden;
            await Response.WriteAsync(JsonConvert.SerializeObject((new { code = 403 })));
        }

    }
}
